from django.db import models
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _

from jiaozi.utils import float_value, get_order_code


bill_type_choices = ((1, '销售收入'), (2, '采购支出'))
pay_type_choices = ((1, '购买VIP'), (2, '购买商品'))


class PayRecord(models.Model):
    # 微信支付
    out_trade_no = models.CharField(verbose_name=_('唯一订单号'), max_length=64, null=True, blank=True, unique=True)
    is_payed = models.BooleanField(verbose_name=_('已支付'), default=False)
    pay_type = models.SmallIntegerField(verbose_name='支付类型', null=True, default=1, choices=pay_type_choices)
    sales_order_id = models.BigIntegerField(verbose_name='订单ID', null=True, blank=True)
    user = models.ForeignKey(
        'app.WxUser',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name=_('关联用户')
    )
    openid = models.CharField(verbose_name=_('OpenID'), max_length=100, null=True, blank=True)
    body = models.CharField(verbose_name=_('商品描述'), max_length=255, null=True, blank=True)
    transaction_id = models.CharField(verbose_name=_('微信支付订单号'), max_length=64, null=True, blank=True)
    total_fee = models.BigIntegerField(verbose_name=_('订单总额,单位为分'), null=True, blank=True)
    pay_time = models.DateTimeField(verbose_name=_('支付时间'), null=True, blank=True)
    pay_no = models.CharField(verbose_name=_('支付唯一订单号'), null=True, blank=True, max_length=64, unique=True)
    code_url = models.CharField(verbose_name=_('二维码地址'), null=True, blank=True, max_length=100)
    nonce_str = models.CharField(verbose_name=_('随机字符串'), null=True, blank=True, max_length=32)

    datetime_created = models.DateTimeField(verbose_name=_('创建时间'), auto_now_add=True)
    datetime_updated = models.DateTimeField(verbose_name=_('更新时间'), auto_now=True)

    objects = models.Manager()

    def make_out_trade_no(self):
        if not self.out_trade_no:
            self.out_trade_no = get_order_code()

    class Meta:
        ordering = ['-pk']
        verbose_name = _('微信支付')
        verbose_name_plural = verbose_name

    def __str__(self):
        return '{0}'.format(self.out_trade_no)


@receiver(pre_save, sender=PayRecord)
def pre_save_pay_record(sender, instance, **kwargs):
    """
    保存前自动创建订单号
    """
    instance.make_out_trade_no()


class MoneyIo(models.Model):
    amount = models.DecimalField(verbose_name=_('金额'), default=0, max_digits=12, decimal_places=2)
    amount_total = models.DecimalField(
        verbose_name=_('累计金额'), default=0, null=True, blank=True, max_digits=12, decimal_places=2)
    amount_current = models.DecimalField(
        verbose_name=_('当前金额'), default=0, null=True, blank=True, max_digits=12, decimal_places=2)
    bill_type = models.SmallIntegerField(verbose_name=_('收支类型'), null=True, choices=bill_type_choices)
    notes = models.CharField(verbose_name=_('备注'), max_length=255, default='', blank=True)
    datetime_created = models.DateTimeField(verbose_name=_('创建时间'), auto_now_add=True)
    datetime_updated = models.DateTimeField(verbose_name=_('更新时间'), auto_now=True)

    objects = models.Manager()

    class Meta:
        ordering = ['-id']
        verbose_name = _('收支流水')
        verbose_name_plural = verbose_name

    def update_amount(self):
        """
        自动更新 累计金额 和 当前金额
        """
        pre_record_amount_total = 0
        pre_record_amount_current = 0
        pre_records = MoneyIo.objects.order_by('-pk')
        if self.pk:
            pre_records = pre_records.filter(pk__lt=self.pk)
        # 获取前一个记录
        pre_record = pre_records.first()
        if pre_record:
            pre_record_amount_total = pre_record.amount_total
            pre_record_amount_current = pre_record.amount_current
        # 计算当前金额
        amount = float_value(self.amount)
        self.amount_current = amount + float_value(pre_record_amount_current)
        # 计算累计金额
        if amount > 0:
            self.amount_total = amount + float_value(pre_record_amount_total)
        else:
            self.amount_total = float_value(pre_record_amount_total)

    def __str__(self):
        return "{} {} {}".format(self.amount, self.amount_total, self.amount_current)


@receiver(pre_save, sender=MoneyIo)
def pre_save_money_io(sender, instance, **kwargs):
    instance.update_amount()
